#include "Tablero.h"
#include "Bloque.h"
#include "Buttons.h"
#include "miniBars.h"
#include "Estrella.h"
#include "CeldasEspeciales.h"
#include <sstream>

using ColorCelda::color;
using ColorCelda::rojo;
using ColorCelda::azul;
using ColorCelda::amarillo;
using ColorCelda::verde;
using ColorCelda::violeta;
using std::string;

#define MAX_FILS 12
#define MAX_COLS 12
#define WIDTH_INI 200

Tablero::Tablero(){
	this->background.load("backgroundJuego.png");
	this->invisibleImg.load("fondoInvisible.gif");
	this->pathBloque = "bloque.gif";
	this->estado = quieto;
}

Tablero::Tablero(const Json::Value& json){
	this->background.load("backgroundJuego.png");
	this->invisibleImg.load("fondoInvisible.gif");
	this->pathBloque = "bloque.gif";
	this->estado = quieto;
	this->actualizar(json);
}

void Tablero::setBackground(const string& path){
	this->background.load(path);
}

void Tablero::setImgBloque(const string& path){
	this->pathBloque = path;
}

Estado sigEstado(const Estado& state){
	if (state == quieto){
		return explotando;
	} else if (state == explotando){
		return bajando;
	} else {
		return quieto;
	}
}

Estado Tablero::getEstado(){
	return this->estado;
}

void Tablero::actualizar(const Json::Value& json){
	this->cantFils = json.get("cantFilas",0).asUInt();
	this->cantCols = json.get("cantColumnas",0).asUInt();
	if (this->tablero.empty()){
		for (unsigned i = 0; i < this->cantCols*this->cantFils; i++){
			this->tablero.push_back(NULL);
		}
	}
	for (unsigned i = 0; i < this->cantCols*this->cantFils; i++){
		std::stringstream s2;
		s2 << "Celda " << i;
		Json::Value aCelda = json["tablero"][s2.str()];
		unsigned x = i % this->cantCols;
		unsigned y = (i - x)/this->cantCols;
		this->actualizarCelda(aCelda,x,y);
	}
	this->estado = sigEstado(this->estado);
}

ColorCelda::color Tablero::decideColor(unsigned num){
	switch (num){
		case 1:
			return verde;
		case 2:
			return rojo;
		case 3:
			return violeta;
		case 4:
			return azul;
		default:
			return amarillo;
	}
}

void Tablero::actualizarCelda(const Json::Value& json,unsigned x, unsigned y){
	Celda* celda;
	unsigned num = json["numero"].asUInt();
	if (!json["estado"].asBool()){
		if (this->estado == explotando){
			celda = new Explosion(x,y);
		} else {
			celda = new Invisible(x,y);
		}
	} else if (num==0){
		celda = new Bloque(x,y,this->pathBloque);
	} else if (num == 6){
		celda = new Estrella(x,y);
	} else if (json["miniBarVertical"].asBool()){
		celda = new MiniBarV(x,y,this->decideColor(num));
	} else if (json["miniBarHorizontal"].asBool()){
		celda = new MiniBarH(x,y,this->decideColor(num));
	} else {
		celda = new Button(x,y,this->decideColor(num));
	}
	Celda*& aux = this->tablero[this->cantCols*y + x];
	if (aux != NULL){
		delete aux;
	}
	aux = celda;
}

void Tablero::dibujar(sdlSurface& surface,int x,int y){
	surface.applySurface(x,y,this->background);
	int width = this->tablero[0]->width();
	int height = this->tablero[0]->height();
	int posX = (MAX_COLS*width - this->cantCols*width)/2;
	int posY = (MAX_FILS*height - this->cantFils*height)/2;
	SDL_Rect clip;
	clip.x = posX;
	clip.y = posY;
	clip.w = this->cantCols*width;
	clip.h = this->cantFils*height;

	this->invisibleImg.applySurface(0,0,this->background,&clip);
	for (std::vector<Celda*>::iterator it = this->tablero.begin();
	it != this->tablero.end(); ++it){
		(*it)->dibujar(this->invisibleImg);
		(*it)->setOffset(posX + WIDTH_INI,posY);
	}
	posX += x;
	posY += y;
	surface.applySurface(posX,posY,this->invisibleImg);
}

bool Tablero::handleEvent(const SDL_Event& event, unsigned& x,unsigned& y){
	for (std::vector<Celda*>::iterator it = this->tablero.begin();
	it != this->tablero.end(); ++it){
		if ((*it)->wasClicked(event)){
			(*it)->getXY(x,y);
			return true;
		}
	}
	return false;
}

Tablero::~Tablero(){
	for (std::vector<Celda*>::iterator it = this->tablero.begin();
	it != this->tablero.end(); ++it){
		delete *it;
	}
}
